<?php
namespace app\common\model;

use think\Db;
use think\Validate;

class ShopGoodsModel extends BaseModel
{
    protected $name = 'shop_goods'; //定义栏目表
    //开启自动写入时间戳
    protected $autoWriteTimestamp = true;
    // 定义自动完成的属性
    protected $auto = []; //新增修改
    protected $insert = []; //插入
    protected $update = []; //修改

    /**
     * 读取缩略图
     * @param $value
     * @param $data
     * @return string
     */
    protected function getGoodsThumbAttr($value, $data)
    {
        if (empty($data['album'])) {
            return '';
        } else {
            $album = explode('|', $data['album']);
            return $album[0];
        }
    }

    protected function setGoodsContentExtendAttr($value, $data)
    {
        if ($data['goods_content_extend']) {
            foreach ($data['goods_content_extend']['key'] as $k => $v) {
                $list[$k] = $v . ":" . $data['goods_content_extend']['value'][$k];
            }
            $list = implode(",", $list);
            return $list;
        }
        return '';
    }

    /*修改器*/

    /**
     * 读取商品信息
     * @param $goodsId
     * @return array
     */
    public function getInfo($goodsId)
    {
        $goodsInfo      = $this->where('goods_id', $goodsId)->find();
        $goodsInfo      = $goodsInfo->append(['goods_thumb'])->toArray();
        $goodsDataModel = new ShopGoodsDataModel();
        $goodsData      = $goodsDataModel->where('goods_id', $goodsId)->find()->toArray();
        $info           = array_merge($goodsInfo, $goodsData);
        return $info;
    }

    /**
     * 阶梯价、一口价检测
     * @param $sku
     * @return bool
     */
    private function checkPrice($sku)
    {
        //判断为空
        if (count($sku) == 0) {
            $this->error = '请设置价格';
            return false;
        }
        //判断是否同一种定价方式
        foreach ($sku as $k => $v) {
            if (!Validate::is($v['goods_stock'], 'number')) {
                $this->error = '库存必须为数字！';
                return false;
            }
            if (!Validate::is($v['market_price'], 'float')) {
                $this->error = '市场价格式不正确！';
                return false;
            }
            if (!Validate::is($v['goods_price'], 'require')) {
                $this->error = '销售价不能为空！';
                return false;
            }
            if (!Validate::is($v['goods_weight'], 'number')) {
                $this->error = '重量必须为数字！';
                return false;
            }
            $ladder[] = substr_count($v['goods_price'], ':');
        }
        if (count(array_unique($ladder)) == 1) { //格式一致
            return true;
        } else {
            $this->error = '同一商品一口价、阶梯价只能选择一种';
            return false;
        }
    }

    /**
     * 设置促销信息
     * @param $data
     */
    private function setPromotion($data, $goodsId, $action = 'add')
    {
        $presellModel  = new ShopPromotionPresellModel();
        $limitModel    = new ShopPromotionLimitModel();
        $pointModel    = new ShopPromotionPointModel();
        $groupbuyModel = new ShopPromotionGroupbuyModel();
        $auctionModel  = new ShopPromotionAuctionModel();
        if ($action != 'add') { //先删除对应活动商品
            $map['goods_id'] = $goodsId;
            $presellModel->where($map)->delete();
            $limitModel->where($map)->delete();
            $pointModel->where($map)->delete();
            $groupbuyModel->where($map)->delete();
            $auctionModel->where($map)->delete();
        }
        $data['promotion']['goods_id'] = $goodsId;
        switch ($data['promotion_type']) {
            case 1: //预售
                $presellModel->addData($data['promotion']);
                break;
            case 2://秒杀
                $limitModel->addData($data['promotion']);
                break;
            case 3://积分
                $pointModel->addData($data['promotion']);
                break;
            case 4://集采
                $groupbuyModel->addData($data['promotion']);
                break;
            case 5://竞拍
                $data['promotion']['current_price'] = $data['promotion']['start_money'];
                $auctionModel->addData($data['promotion']);
                break;
        }
    }

    /**
     * 添加商品
     * @param $data
     * @return bool
     */
    public function addData($data)
    {
        if ($this->checkPrice($data['sku']) == false) {
            return false;
        }
        //添加主表数据
        $data['attr_ids']   = '';
        $data['attr_names'] = '';
        if ($data['is_attr'] == 1) { //获取规格对应值
            foreach ($data['attr'] as $v) {
                $attrId[]   = $v['attr_id'];
                $attrName[] = $v['attr_name'];
            }
            $data['attr_ids']   = implode(',', $attrId);
            $data['attr_names'] = implode(',', $attrName);
        }
        if (in_array($data['promotion_type'], [1, 2, 4, 5])) {
            $time                         = time();
            $data['promotion_begin_time'] = strtotime($data['promotion']['begin_time']);
            $data['promotion_end_time']   = strtotime($data['promotion']['end_time']);
            if ($time < $data['promotion_begin_time']) {
                $data['promotion_status'] = 0;  //未开始
            } elseif ($time > $data['promotion_begin_time'] && $time < $data['promotion_end_time']) {
                $data['promotion_status'] = 1; //正在进行中
            } else {
                $data['promotion_status'] = -1; //已结束
            }
        }
        $this->isUpdate(false)->allowField(true)->save($data);
        //添加附表数据
        $goodsData['goods_id'] = $this->getData('goods_id');
        $goodsData['content']  = $data['content'];
        $goodsData['extend']  = $data['extend'];
        $shopGoodsDataModel = new ShopGoodsDataModel();
        $shopGoodsDataModel->addData($goodsData);
        //添加sku数据
        $goodsSkuModel = new ShopGoodsSkuModel();
        foreach ($data['sku'] as $k => $v) {
            $data['sku'][$k]['goods_id'] = $this->getData('goods_id');
        }
        $goodsSkuModel->saveAll($data['sku']);
        //添加扩展属性
        if ($data['extend_id'] > 0) {
            $goodsExtendModel = new ShopGoodsExtendModel();
            $extend           = $data['extend'];
            $extendList       = [];
            foreach ($extend as $k => $v) {
                unset($v['id']); //强制添加
                if (is_array($v['value'])) {
                    foreach ($v['value'] as $val) {
                        $v['cid']      = $this->getData('cid');
                        $v['site_id']  = $data['site_id'];
                        $v['goods_id'] = $this->getData('goods_id');
                        $v['value']    = $val;
                        $extendList[]  = $v;
                    }
                } else {
                    $v['cid']      = $this->getData('cid');
                    $v['site_id']  = $data['site_id'];
                    $v['goods_id'] = $this->getData('goods_id');
                    $extendList[]  = $v;
                }
            }
            if (!empty($extendList)) {
                $goodsExtendModel->saveAll($extendList);
            }
        }
        //商品促销设置
        $this->setPromotion($data, $this->getData('goods_id'), 'add');
        return true;
    }

    /**
     * 编辑商品
     */
    public function editData($data)
    {
        if (count($data['sku']) == 0) {
            $this->error = '请设置价格';
            return false;
        }
        $goodsInfo = $this->get($data['goods_id']);
        //添加主表数据
        $data['attr_ids']   = '';
        $data['attr_names'] = '';
        if ($data['is_attr'] == 1) { //获取规格对应值
        if($data['attr']){
           foreach ($data['attr'] as $v) {
                               $attrId[]   = $v['attr_id'];
                               $attrName[] = $v['attr_name'];
                          }
                          $data['attr_ids']   = implode(',', $attrId);
                          $data['attr_names'] = implode(',', $attrName);
        }

        }
        if (in_array($data['promotion_type'], [1, 2, 4, 5])) {
            $time                         = time();
            $data['promotion_begin_time'] = strtotime($data['promotion']['begin_time']);
            $data['promotion_end_time']   = strtotime($data['promotion']['end_time']);
            if ($time < $data['promotion_begin_time']) {
                $data['promotion_status'] = 0;  //还未开始
            } elseif ($time > $data['promotion_begin_time'] && $time < $data['promotion_end_time']) {
                $data['promotion_status'] = 1; //正在进行中
            } else {
                $data['promotion_status'] = -1; //已结束
            }
        }
        $this->isUpdate(true)->allowField(true)->save($data);
        //修改附表数据
        $goodsData['goods_id'] = $data['goods_id'];
        $goodsData['content']  = $data['content'];
//        $goodsData['extend']  = $data['extend'];
        $shopGoodsDataModel = new ShopGoodsDataModel();
        $shopGoodsDataModel->save($goodsData,['goods_id'=>$data['goods_id']]);
        //添加sku数据
        $goodsSkuModel = new ShopGoodsSkuModel();
        $isUpdate      = false;
        foreach ($data['sku'] as $k => $v) {
            if (isset($v['sku_id'])) {
                $isUpdate = true;
                break;
            }
        }
        foreach ($data['sku'] as $k => $v) {
            $data['sku'][$k]['goods_id'] = $data['goods_id'];
        }
        if ($isUpdate == false) { //新增需先删除旧sku数据
            $goodsSkuModel->where('goods_id', $data['goods_id'])->delete();
        }
        $goodsSkuModel->saveAll($data['sku']);
        //添加扩展属性
        $goodsExtendModel = new ShopGoodsExtendModel();
        if ($data['extend_id'] > 0) {
            $extend     = $data['extend'];
            $extendList = [];
            foreach ($extend as $k => $v) {
                if (empty($v['id'])) {
                    unset($v['id']);
                }
                if (is_array($v['value'])) {
                    foreach ($v['value'] as $val) {
                        $v['cid']      = $this->getData('cid');
                        $v['site_id']  = $data['site_id'];
                        $v['goods_id'] = $this->getData('goods_id');
                        $v['value']    = $val;
                        $extendList[]  = $v;
                    }
                } else {
                    $v['cid']      = $this->getData('cid');
                    $v['site_id']  = $data['site_id'];
                    $v['goods_id'] = $this->getData('goods_id');
                    $extendList[]  = $v;
                }
            }
            if ($goodsInfo['extend_id'] != $data['extend_id']) { //扩展属性改变先删除原扩展属性
                $goodsExtendModel->where('goods_id', $this->getData('goods_id'))->delete();
            }
            if (!empty($extendList)) {
                $goodsExtendModel->saveAll($extendList);
            }
        } else { //删除属性
            $goodsExtendModel->where('goods_id', $this->getData('goods_id'))->delete();
        }
        //商品促销设置
        $this->setPromotion($data, $data['goods_id'], 'edit');
        return true;
    }

    /**
     * 删除商品
     * @param $goodsId
     */
    public function delData($goodsId)
    {
        $map['goods_id'] = $goodsId;
        Db::table('shop_goods')->where($map)->delete();
        Db::table('shop_goods_data')->where($map)->delete();
        Db::table('shop_goods_sku')->where($map)->delete();
        Db::table('shop_goods_extend')->where($map)->delete();
        Db::table('shop_promotion_groupbuy')->where($map)->delete();
        Db::table('shop_promotion_limit')->where($map)->delete();
        Db::table('shop_promotion_presell')->where($map)->delete();
        Db::table('shop_promotion_auction')->where($map)->delete();
        Db::table('shop_promotion_point')->where($map)->delete();
        Db::table('shop_promotion_auction')->where($map)->delete();
        return true;
    }

    /**
     * 检测商品活动状态
     * @param $goodsId
     * @param $promotionType
     * @return array|int
     */
    public function checkPromotionGoods($goodsId, $promotionType)
    {
        $time = time();
        $arr  = ['1' => 'ShopPromotionPresellModel', '2' => 'ShopPromotionLimitModel', '3' => 'ShopPromotionPointModel', '4' => 'ShopPromotionGroupbuyModel', '5' => 'ShopPromotionAuctionModel'];
        $info = model($arr[$promotionType])->where('goods_id', $goodsId)->find()->toArray();
        if ($promotionType == 3) { //积分商品直接返回商品信息
            return $info;
        }
        if ($time < $info['begin_time']) {
            $promotion_status = 0;  //还未开始
        } elseif ($time > $info['begin_time'] && $time < $info['end_time']) {
            $promotion_status = 1; //正在进行中
        } else {
            $promotion_status = -1; //已结束
        }
        $this->where('goods_id', $goodsId)->setField('promotion_status', $promotion_status);
        if ($promotion_status == 1) {
            return $info;
        }
        return $promotion_status;
    }

    /**
     * 刷新指定活动商品
     * @param $promotionType
     */
    public function refreshPromotionGoods($promotionType, $goodsIds = '')
    {
        $time = time();
        if (in_array($promotionType, [1, 2, 4, 5])) { //更新活动商品状态
            $map = [];
            if ($goodsIds != '') {
                $map['goods_id'] = ['in', $goodsIds];
            }
            //更新正在进行中状态
            $this->where($map)->where('promotion_status', 0)->where('promotion_begin_time', '<=', $time)->where('promotion_end_time', '>=', $time)->setField('promotion_status', 1);
            //更新结束状态
            $this->where($map)->where('promotion_status', 1)->where('promotion_end_time', '<', $time)->setField('promotion_status', -1);
        }
        return true;
    }

    /**
     * 检测库存
     * @param integer $skuId skuid
     * @param integer $num 购买数量
     * @return integer 库存-数量后的值
     */
    public function checkStock($skuId, $num)
    {
        $skuInfo    = ShopGoodsSkuModel::get($skuId);
        $goodsStock = $skuInfo->getData('goods_stock');
        return $goodsStock - $num;
    }

    /**
     * 刷新库存 键为skuID 值为购买数
     * $stocks=['1'=>'6','3'=>10,'10'=>100]
     * @param $skuIds
     * @param $nums
     */
    public function refrashStock($stocks)
    {
        $goodsSkuModel = new ShopGoodsSkuModel();
        $info          = $goodsSkuModel->where('sku_id', 'in', array_keys($stocks))->column('goods_stock,goods_name,sku_name', 'sku_id');
        foreach ($stocks as $k => $v) {
            if ($v > $info[$k]['goods_stock']) {
                $this->error = '[' . $info[$k]['goods_name'] . ' ' . $info[$k]['sku_name'] . ']库存不足';
                return false;
            }
        }
        return true;
    }

    /**
     * 计算商品价格
     * @param $goodsPrice
     * @param $num
     * @return bool
     */
    public function calcPrice($goodsPrice, $num)
    {
        $price = format_goods_price($goodsPrice);
        if ($price['is_ladder'] == 1) {
            $goodsLadderNum = array_keys($price['ladder_price']);
            $index          = count($goodsLadderNum) - 1; //最终索引
            if ($num >= $goodsLadderNum[$index]) { //最后一条
                $resultPrice = $price['ladder_price'][$goodsLadderNum[$index]];
            }
            if ($num >= $goodsLadderNum[0] && $num < $goodsLadderNum[$index]) {
                foreach ($goodsLadderNum as $k => $v) {
                    if ($k == $index) {
                        continue;
                    }
                    if ($num >= $v && $num < $goodsLadderNum[$k + 1]) {
                        $resultPrice = $price['ladder_price'][$v];
                    }
                }
            }
            if ($num < $goodsLadderNum[0]) { //第一条
                $this->error = '未达到阶梯价订购最低标准';
                return false;
            }
        } else {
            $resultPrice = $price['simple_price'];
        }
        return $resultPrice;
    }

}
